from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection
from django import http
from random import randint

from meiduo_mall.libs.captcha.captcha import captcha
from meiduo_mall.utils.response_code import RETCODE
# from meiduo_mall.libs.yuntongxun.sms import CCP
from celery_tasks.sms.tasks import send_sms_code
from . import constants
import logging

logger = logging.getLogger('django')

class ImageCodeView(View):
    """图形验证码"""
    def get(self, request, uuid):
        # 调用sdk生成图形验证码
        # name: 随机字符串
        # text: 图形验证码字符
        # image_code: 图形验证码图片数据
        name, text, image_code = captcha.generate_captcha()
        # 创建redis连接客户端对象
        redis_conn = get_redis_connection('verify_code')
        # 存储图形验证码字符内容到redis
        # redis_conn.setex(key, 过期时间, value)
        redis_conn.setex(uuid, 300, text)
        # 响应
        return http.HttpResponse(image_code, content_type='image/png')


class SMSCodeView(View):
    """短信验证码"""
    def get(self, request, mobile):
        # 1.创建redis连接对象
        redis_conn = get_redis_connection('verify_code')
        # 1.1 尝试获取此手机号是否有发送过短信的标识
        send_flag = redis_conn.get('send_flag_%s' % mobile)
        # 1.2 判断是否有发送标识
        if send_flag:
            return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '频繁发送短信'})

        # 2.接收查询参数数据
        query_dict = request.GET
        image_code_client = query_dict.get('image_code')
        uuid = query_dict.get('uuid')
        # 3.校验
        if all([image_code_client, uuid]) is False:
            return http.HttpResponseForbidden('缺少必传参数')

        # 3.1校验图形验证码是否正确
        # 获取redis中当前用户的图形验证码
        image_code_server = redis_conn.get(uuid)

        # 3.2 如果图形验证码已过期
        if image_code_server is None:
            return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图形验证码已过期'})
        # 从redis里面获取出来的数据都是bytes类型 [] {} {}
        # 3.3 将bytes类型转换成字符串
        image_code_server = image_code_server.decode()
        # 3.4 用户图形验证码和redis中图形验证码比对
        if image_code_client.lower() != image_code_server.lower():
            return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图形验证码填写错误'})

        # 4.发短信
        sms_code = '%06d' % randint(0, 999999)
        # 为了方便后期测试将短信验证码输出到控制台
        logger.info(sms_code)

        # 4.1 用容联云平台发短信
        # CCP().send_template_sms(to='接收短信的手机号', datas=['短信验证码', '提示用户多少分钟'], temp_id='短信模板id')
        # print(CCP().send_template_sms(to=mobile, datas=[sms_code, 5], temp_id=1))
        # 如果不能使用自定义模板时模板id只能写1
        # CCP().send_template_sms(mobile, [sms_code, 5], 1)
        # send_sms_code(mobile, sms_code)  # 还是在当前线程执行
        send_sms_code.delay(mobile, sms_code)  # 生产任务,将任务添加到仓库
        # 创建redis管道对象
        pl = redis_conn.pipeline()
        # 4.2 为了后期注册时校验短信验证码是否填写正确,我们将发出去的短信验证码缓存在redis
        # redis_conn.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRE, sms_code)
        pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRE, sms_code)
        # 4.3 向redis数据库存储一个标识,标识此手机号60s内已发送过短信
        # redis_conn.setex('send_flag_%s' % mobile, constants.SMS_CODE_FLAG_EXPIRE, 1)
        pl.setex('send_flag_%s' % mobile, constants.SMS_CODE_FLAG_EXPIRE, 1)
        # 执行管道
        pl.execute()
        # 5.响应json
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})


